﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using NP.BPMReportPlatform.BHGPSSP.Dtos;
using NP.BPMReportPlatform.BPMPlatform;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Engine;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.Utils;
using SqlSugar;
using Volo.Abp.Application.Dtos;

namespace NP.BPMReportPlatform.BHGPSSP
{
    public class BHGPSSPService : BPMReportPlatformAppService, IBHGPSSPService
    {
        #region Variables

        private readonly SqlSugarClient _db;
        private readonly SqlSugarClient _dbPlatform;
        private readonly SqlSugarClient _dbEngine;
        private readonly IBPMUtilsAppService _bPMUtilsApp;
        private readonly IBPMPlatformAppService _iBPMPlatformApp;

        #endregion

        #region Constructor

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sqlSugarAppService"></param>
        public BHGPSSPService(ISqlSugarAppService sqlSugarAppService, IBPMUtilsAppService bPMUtilsApp
            , IBPMPlatformAppService iBPMPlatformApp)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _bPMUtilsApp = bPMUtilsApp;
            _iBPMPlatformApp = iBPMPlatformApp;
        }

        #endregion


        public async Task<ISugarQueryable<GetBHGPSSPOutput>> GetQueryable(GetBHGPSSPInput input)
        {
            var currentUserId = Guid.Empty;
            var instanceIds = new List<string>();
            if (!input.IsQueryAll)
            {
                var currentUserDto = await _dbPlatform.Queryable<Users>()
                    .Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).FirstAsync();
                if (currentUserDto != null)
                {
                    currentUserId = currentUserDto.UserId;
                    instanceIds = await _dbEngine.Queryable<Tasks, Instances>((t, i) => t.InstanceNumber == i.Number)
                        .Where((t, i) => t.UserId == currentUserId.ToString() && i.ProcessName == "不合格评审审批")
                        .Select((t, i) => t.InstanceNumber).Distinct().ToListAsync();
                }
            }

            var listQueryable = _db
                .Queryable<BHGPSSPHeader, BusinessProcessesNew>((a, b) => a.InstanceNumber == b.InstanceId)
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber),
                    (a, b) => a.InstanceNumber == input.InstanceNumber)
                .WhereIF(!input.OrderStatus.IsNullOrEmpty(),
                    (a, b) => SqlFunc.ContainsArray(input.OrderStatus.ToArray(), b.ProcessStatusCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName),
                    (a, b) => b.StartUserName.Contains(input.AddUserName))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null,
                    (a, b) => b.StartTime >= input.StartCreationTime &&
                              b.StartTime <= input.EndCreationTime)
                .WhereIF(!input.IsQueryAll,
                    (a, b) => b.StartUserId == (currentUserId))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Title),
                    (a, b) => a.Title.Contains(input.Title))
                .WhereIF(!string.IsNullOrWhiteSpace(input.ReviewProject),
                    (a, b) => a.ReviewProject.Equals(input.ReviewProject))
                .WhereIF(!string.IsNullOrWhiteSpace(input.DisposalPlan),
                    (a, b) => a.DisposalPlan.Contains(input.DisposalPlan))
                .WhereIF(instanceIds.Count > 0,
                    (a, b) => instanceIds.Contains(a.InstanceNumber))
                .Select((a, b) => new GetBHGPSSPOutput()
                {
                    InstanceNumber = a.InstanceNumber,
                    ProcessStartUserName = b.StartUserName,
                    Title = a.Title,
                    CCUsersName = a.CCUsersName,
                    Content = a.Content,
                    DisposalPlan = a.DisposalPlan,
                    DisposalPlanDescription = a.DisposalPlanDescription,
                    OrderStatus = b.ProcessStatusName,
                    ProcessStartTime = b.StartTime,
                    ReviewProject = a.ReviewProject,
                });

            return listQueryable;
        }

        public async Task<PagedResultDto<GetBHGPSSPOutput>> GetAllAsync(GetBHGPSSPInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = await GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);
            listViewDto.ForEach(x => { x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId); });

            //返回结果
            return new PagedResultDto<GetBHGPSSPOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<GetBHGPSSPOutput>> ExportAsync(GetBHGPSSPInput input)
        {
            var listQueryable = await GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }

        #region 新不合格评审审批
        private async Task<ISugarQueryable<NewBHGPSSPOutput>> GetQueryable(GetNewBHGPSSPInput input)
        {
            var currentUserId = Guid.Empty;
            var instanceIds = new List<string>();
            if (!input.IsQueryAll)
            {
                var currentUserDto = await _dbPlatform.Queryable<Users>()
                    .Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).FirstAsync();
                if (currentUserDto != null)
                {
                    currentUserId = currentUserDto.UserId;
                    instanceIds = await _dbEngine.Queryable<Tasks, Instances>((t, i) => t.InstanceNumber == i.Number)
                        .Where((t, i) => t.UserId == currentUserId.ToString() && i.ProcessName == "新不合格评审审批")
                        .Select((t, i) => t.InstanceNumber).Distinct().ToListAsync();
                }
            }

            var listQueryable = _db.Queryable<NewBHGPSSPHeader,NewBHGPSSPDetail, BusinessProcessesNew>(
                (x, m, b) => new JoinQueryInfos(JoinType.Left, x.InstanceNumber == m.InstanceNumber, JoinType.Left, x.InstanceNumber == b.InstanceId))
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber),(x, m, b) => x.InstanceNumber == input.InstanceNumber)
                .WhereIF(!input.OrderStatus.IsNullOrEmpty(),(x,m, b) => SqlFunc.ContainsArray(input.OrderStatus.ToArray(), b.ProcessStatusCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName),(x, m, b) => b.StartUserName.Contains(input.AddUserName))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null,(x, m, b) => b.StartTime >= input.StartCreationTime && b.StartTime <= input.EndCreationTime)
                .WhereIF(!input.IsQueryAll,(x, m, b) => b.StartUserId == (currentUserId))
                .WhereIF(instanceIds.Count > 0,(x, m, b) => instanceIds.Contains(x.InstanceNumber))
                .Select((x, m, b) => new NewBHGPSSPOutput()
                {
                    InstanceNumber = x.InstanceNumber,
                    AddUserName = b.StartUserName,
                    CreateTime= x.AddTime,
                    OrderStatus = b.ProcessStatusName,
                    Factory=x.Factory,
                    MaterialCode=x.MaterialCode,
                    MaterialName=x.MaterialName,
                    MaterialType=x.MaterialType,
                    Supplier=x.Supplier,
                    BatchNo=x.BatchNo,
                    InspectionLot=x.InspectionLot,
                    CCUsersName = x.CCUsersName,
                    DisposalPlan = x.DisposalPlan,
                    DisposalPlanDescription=x.DisposalPlanDescription,
                    TestProjectName =m.TestProjectName,
                    TestProjectNorm=m.TestProjectNorm,
                    TestResult=m.TestResult,
                    UnqualifiedDescription=m.UnqualifiedDescription,
                });

            return listQueryable;
        }

        public async Task<PagedResultDto<NewBHGPSSPOutput>> GetAllAsync(GetNewBHGPSSPInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = await GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);
            listViewDto.ForEach(x => { x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId); });

            //返回结果
            return new PagedResultDto<NewBHGPSSPOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<NewBHGPSSPOutput>> ExportAsync(GetNewBHGPSSPInput input)
        {
            var listQueryable = await GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }
        #endregion
    }
}